package com.karry.web;

import com.karry.pojo.User;
import com.karry.service.UserService;
import com.karry.service.impl.UserServiceImpl;
import com.karry.util.FieldCheckUtil;
import com.karry.util.JsonUtil;
import com.karry.util.RecordUtil;
import com.karry.vo.ResultInfo;
import org.apache.commons.io.FileUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

@WebServlet("/user")
@MultipartConfig //这个用于接收 enctype="multipart/form-data" 格式内容
public class UserServlet extends HttpServlet {

    //获取user服务层
    UserService us = new UserServiceImpl();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置首页导航的高亮值
        req.setAttribute("menu_page", "user");
        String method = req.getParameter("actionName").trim();

        System.out.println("user_actionName:" + method);

        switch (method){
            //登录
            case "userLogin":
                userLogin(req, resp);
                break;
                //注册
            case  "userRegister":
                userRegister(req, resp);
                break;
                //正常改密
            case "updatePwd":
                updatePwd(req, resp);
                break;
                //修改普通信息
            case "updateUser":
                updateUser(req, resp);
                break;
                //跳转个人中心页面
            case "userCenter":
                userCenter(req, resp);
                break;
                //账号登出
            case "userLogout":
                userLogOut(req, resp);
                break;
                //检查昵称合法性
            case "checkNick":
                checkNick(req, resp);
                break;
                //获取头像
            case "userHead":
                userHead(req, resp);
                break;
                //修改邮箱
            case "updateEmail":
                updateEmail(req, resp);
                break;
                //忘记密码
            case "forgetPwd":
                forgetPwd(req, resp);
                break;
                //删除账号
            case "delete":
                deleteUser(req, resp);
                break;
                //恢复账号或者解禁账号
            case "liveOrOpen":
                liveOrOpenUser(req, resp);
                break;
                //封禁账号
            case "close":
                closeUser(req, resp);
                break;
            default:
                req.getRequestDispatcher("login.jsp").forward(req, resp);
                break;
        }

    }

    /**
     *  删除账号
     * */
    private void deleteUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userID = request.getParameter("id");
        int id = 0;
        if (userID != null && userID.length() > 0){
            id = Integer.parseInt(userID);
        }

        ResultInfo<User> resultInfo = us.deleteUser(id, request);
        JsonUtil.toJson(response, resultInfo);
    }


    /**
     *  封禁账号
     * */
    private void closeUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userID = request.getParameter("id");
        int id = 0;
        if (userID != null && userID.length() > 0){
            id = Integer.parseInt(userID);
            System.out.println("id:" + id);
        }

        ResultInfo<User> resultInfo = us.closeUser(id, request);
        JsonUtil.toJson(response, resultInfo);
    }


    /**
     *  解禁或者恢复账号
     * */
    private void liveOrOpenUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userID = request.getParameter("id");
        int id = 0;
        if (userID != null && userID.length() > 0){
            id = Integer.parseInt(userID);
        }

        ResultInfo<User> resultInfo = us.liveOrOpenUser(id, request);
        JsonUtil.toJson(response, resultInfo);
    }


        /**
         *  找回密码
         * */
    private void forgetPwd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String email = request.getParameter("email");
        String code = request.getParameter("code");
        String pwd = request.getParameter("userPwd");

        //验证邮箱与验证码
        //获取session
        Object e = request.getSession().getAttribute("email");
        Object c = request.getSession().getAttribute("code");

        //验证成功
        if (e != null && e.toString().equals(email) && c != null && c.toString().equals(code)){
            request.getSession().removeAttribute("email");
            request.getSession().removeAttribute("code");
            request.getSession().removeAttribute("sendTime");
        }else {
            ResultInfo<User> resultInfo = new ResultInfo<>();
            resultInfo.setCode(0);
            resultInfo.setMsg("验证码错误");
            // 2. 将resultInfo对象存到request作用域中
            request.setAttribute("resultInfo", resultInfo);
            // 3. 请求转发跳转到个人中心页面 （user?actionName=userCenter）
            request.getRequestDispatcher("forgetPwd.jsp").forward(request, response);
            return;
        }

        //对账号和密码还有邮箱进行合法性验证
        if (!FieldCheckUtil.checkName(pwd)){
            ResultInfo<User> resultInfo = new ResultInfo<>();
            resultInfo.setCode(0);
            resultInfo.setMsg("密码格式错误");
            // 2. 将resultInfo对象存到request作用域中
            request.setAttribute("resultInfo", resultInfo);
            // 3. 请求转发跳转到个人中心页面 （user?actionName=userCenter）
            request.getRequestDispatcher("forgetPwd.jsp").forward(request, response);
            return;
        }
        //改密（成功跳转登录，失败回原地）
        ResultInfo<Integer> resultInfo = us.updatePwd_forget(email, pwd);
        if (resultInfo.getCode() == 1){
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }else {
            // 2. 将resultInfo对象存到request作用域中
            request.setAttribute("resultInfo", resultInfo);
            // 3. 请求转发跳转到个人中心页面 （user?actionName=userCenter）
            request.getRequestDispatcher("forgetPwd.jsp").forward(request, response);

        }
    }

    /**
     *  修改用户邮箱
     * */
    private void updateEmail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String email = request.getParameter("email");
        String code = request.getParameter("code");

        //获取session
        Object e = request.getSession().getAttribute("email");
        Object c = request.getSession().getAttribute("code");

        //验证成功
        if (e != null && e.toString().equals(email) && c != null && c.toString().equals(code)){
            request.getSession().removeAttribute("email");
            request.getSession().removeAttribute("code");
            request.getSession().removeAttribute("sendTime");
        }else {
            ResultInfo<User> resultInfo = new ResultInfo<>();
            resultInfo.setCode(0);
            resultInfo.setMsg("验证码错误");
            // 2. 将resultInfo对象存到request作用域中
            request.setAttribute("resultInfo2", resultInfo);
            // 3. 请求转发跳转到个人中心页面 （user?actionName=userCenter）
            request.getRequestDispatcher("user?actionName=userCenter").forward(request, response);
            return;
        }

        //对账号和密码还有邮箱进行合法性验证
        if (!FieldCheckUtil.checkEmail(email)){
            ResultInfo<User> resultInfo = new ResultInfo<>();
            resultInfo.setCode(0);
            resultInfo.setMsg("邮箱格式错误");
            // 2. 将resultInfo对象存到request作用域中
            request.setAttribute("resultInfo2", resultInfo);
            // 3. 请求转发跳转到个人中心页面 （user?actionName=userCenter）
            request.getRequestDispatcher("user?actionName=userCenter").forward(request, response);
            return;
        }

        User user = (User) request.getSession().getAttribute("user");
        //判断完毕
        ResultInfo<User> resultInfo = us.updateEmail(user.getId(), email);

        if (resultInfo.getCode() == 1){
            //成功直接登出
            userLogOut(request, response);
        } else {
            request.setAttribute("resultInfo2", resultInfo);
            request.getRequestDispatcher("user?actionName=userCenter").forward(request, response);

        }
    }


    /**
     *  用户登录
     *
     *  登录成功修改登录记录
     *  添加操作日志(成功失败都记录)
     */
    private void userLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //可能是邮箱登录
        String name = request.getParameter("userName").trim();
        String pwd = request.getParameter("userPwd").trim();

        ResultInfo<User> resultInfo = us.userSearchByNameAndPwd(name, pwd);

        System.out.println("登录情况:" + resultInfo.toString());
        if (resultInfo.getCode() == 1){
            //登录成功，记录信息
            RecordUtil.insertRecord(1, resultInfo.getResult().getId(), request);
            //查询到指定用户
            //  将用户信息设置到session作用域中
            request.getSession().setAttribute("user", resultInfo.getResult());
            //  判断用户是否选择记住密码（rem的值是1）
            String rem = request.getParameter("rem");
            // 如果是，将用户姓名与密码存到cookie中，设置失效时间，并响应给客户端
            if ("1".equals(rem)) {
                // 得到Cookie对象
                Cookie cookie = new Cookie("user",name + "-" + pwd);
                // 设置失效时间
                cookie.setMaxAge(7*24*60*60);
                // 响应给客户端
                response.addCookie(cookie);
            } else {
                // 如果否，清空原有的cookie对象
                Cookie cookie = new Cookie("user", null);
                // 删除cookie，设置maxage为0
                cookie.setMaxAge(0);
                // 响应给客户端
                response.addCookie(cookie);
            }
            // 重定向跳转到index页面
            response.sendRedirect("index");
        }else {
            //登录失败，记录信息
            User user = us.getUserByName(name);
            if (user != null){
                RecordUtil.insertRecord(0, user.getId(), request);
            }
            // 将resultInfo对象设置到request作用域中
            request.setAttribute("resultInfo", resultInfo);
            // 请求转发跳转到登录页面
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }

    }

    /**
     *
     *
     * 加载头像
     *  1. 获取参数 （图片名称）
     *  2. 得到图片的存放路径 （request.getServletContext().getealPathR("/")）
     *  3. 通过图片的完整路径，得到file对象
     *  4. 通过截取，得到图片的后缀
     *  5. 通过不同的图片后缀，设置不同的响应的类型
     *  6. 利用FileUtils的copyFile()方法，将图片拷贝给浏览器
     * @param request
     * @param response
     */
    private void userHead(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. 获取参数 （图片名称）
        String head = request.getParameter("imageName");
        System.out.println("head:" + head);
        if (head != null && head.length() > 0) {
            //判断文件类型(获取文件后缀)
            String fileType = head.substring(head.lastIndexOf(".") + 1);
            if ("jpg".equalsIgnoreCase(fileType) || "jpeg".equalsIgnoreCase(fileType) || "png".equalsIgnoreCase(fileType)) {

            } else {
                System.out.println("图片类型异常:" + fileType);
                //返回错误码
                response.getWriter().write("2");
                // 5. 关闭资源
                response.getWriter().close();
                return;

            }
        }
        // 2. 得到图片的存放路径 （得到项目的真实路径：request.getServletContext().getealPathR("/")）
        String realPath = request.getServletContext().getRealPath("/WEB-INF/upload/");
        // 3. 通过图片的完整路径，得到file对象
        File file = new File(realPath + "/" + head);
        System.out.println("file:" + file.getAbsolutePath());
        // 4. 通过截取，得到图片的后缀
        String pic = head.substring(head.lastIndexOf(".")+1);
        // 5. 通过不同的图片后缀，设置不同的响应的类型
        if ("PNG".equalsIgnoreCase(pic)) {
            response.setContentType("image/png");
        } else if ("JPG".equalsIgnoreCase(pic) || "JPEG".equalsIgnoreCase(pic)) {
            response.setContentType("image/jpeg");
        } else if ("GIF".equalsIgnoreCase(pic)) {
            response.setContentType("image/gif");
        }
        // 6. 利用FileUtils的copyFile()方法，将图片拷贝给浏览器
        FileUtils.copyFile(file, response.getOutputStream());
    }

    /**
     *  用户注册
     * */
    private void userRegister(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1. 获取参数 （姓名、密码）
        String userName = request.getParameter("userName");
        String userPwd = request.getParameter("userPwd");
        String userEmail = request.getParameter("email");
        String code = request.getParameter("code").trim();

        Object e = request.getSession().getAttribute("email");
        Object c = request.getSession().getAttribute("code");


        //验证成功
        if (e != null && e.toString().equals(userEmail) && c != null && c.toString().equals(code)){
            request.getSession().removeAttribute("email");
            request.getSession().removeAttribute("code");
            request.getSession().removeAttribute("sendTime");
        }else {
            ResultInfo<User> resultInfo = new ResultInfo<>();
            resultInfo.setCode(0);
            resultInfo.setMsg("验证码错误");
            // 将resultInfo对象设置到request作用域中
            request.setAttribute("resultInfo", resultInfo);
            // 请求转发跳转到登录页面
            request.getRequestDispatcher("register.jsp").forward(request, response);
            return;
        }

        //对账号和密码还有邮箱进行合法性验证
        if (!FieldCheckUtil.checkName(userName) || !FieldCheckUtil.checkName(userPwd) || !FieldCheckUtil.checkEmail(userEmail)){
            ResultInfo<User> resultInfo = new ResultInfo<>();
            resultInfo.setCode(0);
            resultInfo.setMsg("账号、密码、邮箱格式错误");
            // 将resultInfo对象设置到request作用域中
            request.setAttribute("resultInfo", resultInfo);
            // 请求转发跳转到登录页面
            request.getRequestDispatcher("register.jsp").forward(request, response);
            return;
        }


        // 2. 调用Service层的方法，返回ResultInfo对象
        ResultInfo<User> resultInfo = us.userRegister(userName, userPwd, userEmail);
        System.out.println("注册情况:" + resultInfo.toString());
        // 3. 判断是否注册成功
        if (resultInfo.getCode() == 1) { // 如果成功

            // 重定向跳转到login页面
            response.sendRedirect("login.jsp");

        } else { // 失败
            // 将resultInfo对象设置到request作用域中
            request.setAttribute("resultInfo", resultInfo);
            // 请求转发跳转到注册页面
            request.getRequestDispatcher("register.jsp").forward(request, response);
        }

    }

    /**
     *  修改用户信息
     * */
    private void updateUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 调用Service层的方法，传递request对象作为参数，返回resultInfo对象
        ResultInfo<User> resultInfo = us.updateUser(request);
        // 2. 将resultInfo对象存到request作用域中
        request.setAttribute("resultInfo", resultInfo);
        // 3. 请求转发跳转到个人中心页面 （user?actionName=userCenter）
        request.getRequestDispatcher("user?actionName=userCenter").forward(request, response);
    }

    /**
     *  修改用户密码
     * */
    private void updatePwd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 调用Service层的方法，传递request对象作为参数，返回resultInfo对象
        ResultInfo<User> resultInfo = us.updatePwd(request);

        System.out.println("修改密码:" + resultInfo.getMsg());

        //改密成功，退出登录
        if (resultInfo.getCode() == 1){
            //request.getRequestDispatcher("user?actionName=userLogOut").forward(request, response);
            //response.sendRedirect("user?actionName=userLogOut");
            userLogOut(request, response);
        }else {
            // 2. 将resultInfo对象存到request作用域中
            request.setAttribute("resultInfo1", resultInfo);
            // 3. 请求转发跳转到个人中心页面 （user?actionName=userCenter）
            request.getRequestDispatcher("user?actionName=userCenter").forward(request, response);

        }

    }

    /**
     * 验证昵称的唯一性
     *  1. 获取参数（昵称）
     *  2. 从session作用域获取用户对象，得到用户ID
     *  3. 调用Service层的方法，得到返回的结果
     *  4. 通过字符输出流将结果响应给前台的ajax的回调函数
     *  5. 关闭资源
     * @param request
     * @param response
     */
    private void checkNick(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. 获取参数（昵称）
        String nick  = request.getParameter("nick");
        // 2. 从session作用域获取用户对象，得到用户ID
        User user = (User) request.getSession().getAttribute("user");
        // 3. 调用Service层的方法，得到返回的结果
        Integer code = us.checkNick(nick, user.getId());
        // 4. 通过字符输出流将结果响应给前台的ajax的回调函数
        response.getWriter().write(code + "");
        // 5. 关闭资源
        response.getWriter().close();
    }


    /**
     * 进入个人中心
     *  1. 设置首页动态包含的页面值
     *  2. 请求转发跳转到index.jsp
     * @param request
     * @param response
     */
    private void userCenter(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1. 设置首页动态包含的页面值
        request.setAttribute("changePage", "user/info.jsp");
        // 2. 请求转发跳转到index
        request.getRequestDispatcher("index.jsp").forward(request, response);

    }

    /**
     * 用户退出
     *  1. 销毁Session对象
     *  2. 删除Cookie对象
     *  3. 重定向跳转到登录页面
     * @param request
     * @param response
     */
    private void userLogOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. 销毁Session对象
        request.getSession().invalidate();
        // 2. 删除Cookie对象
        Cookie cookie = new Cookie("user", null);
        cookie.setMaxAge(0); // 设置0，表示删除cookie
        response.addCookie(cookie);
        // 3. 重定向跳转到登录页面
        response.sendRedirect("login.jsp");
    }


}
